// Package data 提供数据层依赖注入、数据库连接等实现
package data

import (
	"context"
	"time"
	"user/internal/conf"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"

	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// ProviderSet 是 data 层依赖注入的 provider 集合
var ProviderSet = wire.NewSet(NewData, NewDataBase, NewUserRepo, NewMongoClient, NewChatRepo, NewCommentRepo, NewRabbitMQFromConf)

// Data 封装所有数据相关的客户端（如数据库连接）
type Data struct {
	DataBase *gorm.DB // MySQL数据库连接
}

// NewData 创建 Data 实例
// 参数：
//
//	c      - 配置信息
//	logger - 日志
//	db     - MySQL数据库连接
//
// 返回：
//
//	*Data 实例，清理函数，错误
func NewData(c *conf.Data, logger log.Logger, db *gorm.DB) (*Data, func(), error) {
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
	}
	return &Data{
		DataBase: db,
	}, cleanup, nil
}

// NewDataBase 创建 MySQL 数据库连接
// 参数：c - 配置信息
// 返回：*gorm.DB 实例，错误
func NewDataBase(c *conf.Data) (*gorm.DB, error) {
	dsn := "root:e10adc3949ba59abbe56e057f20f883e@tcp(14.103.149.201:3306)/day03?charset=utf8mb4&parseTime=True&loc=Local"
	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, err
	}
	return db, nil
}

// NewMongoClient 创建 MongoDB 客户端，支持连接池参数配置
// 参数：
//
//	c - 配置信息（包含MongoDB配置）
//
// 返回：
//
//	*mongo.Client 实例，错误
func NewMongoClient(c *conf.Data) (*mongo.Client, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	clientOpts := options.Client().ApplyURI(c.Mongo.Uri)
	// 设置最大连接池数，默认100
	if c.Mongo.MaxPoolSize > 0 {
		clientOpts.SetMaxPoolSize(uint64(c.Mongo.MaxPoolSize))
	}
	// 设置最小连接池数，默认0
	if c.Mongo.MinPoolSize > 0 {
		clientOpts.SetMinPoolSize(uint64(c.Mongo.MinPoolSize))
	}
	return mongo.Connect(ctx, clientOpts)
}

// NewRabbitMQFromConf 通过配置创建 RabbitMQ 客户端
func NewRabbitMQFromConf(c *conf.Data) (*RabbitMQ, error) {
	return NewRabbitMQ(c.Rabbitmq.Addr, c.Rabbitmq.Queue)
}
